﻿using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.Net;
using System.Text.RegularExpressions;
using Nextensions.Basic;

namespace Nextensions.Administration
{

    public enum Properties
    {
        Path
    }

    public class IIS6
    {
        public const string WebSiteRootPath = "IIS://localhost/W3SVC/1/Root";
        public const string WebSiteRootPathF = "IIS://{0}/W3SVC/1/Root/{1}";
        public const string DefaultWebSitePath = "IIS://localhost/W3SVC/1";
        private const string VirtualDirSchemaName = "IIsWebVirtualDir";
        private const string AnonymousUserName = "AnonymousUserName";
        private const string AnonymousUserPass = "AnonymousUserPass";
        private const string ServerBindings = "ServerBindings";

        internal static VirtualDirectory[] VirtualDirectories
        {
            get
            {
                List<VirtualDirectory> list = new List<VirtualDirectory>();

                DirectoryEntry root = new DirectoryEntry(WebSiteRootPath);
                DirectoryEntries children = root.Children;

                foreach (DirectoryEntry dir in children)
                {
                    VirtualDirectory vDir = new VirtualDirectory();
                    vDir.Name = dir.Properties["Name"].Value.ToString();
                    vDir.Path = dir.Properties["Path"].Value.ToString();
                    list.Add(vDir);
                }

                return list.ToArray();
            }
        }

        public static void SetVirtualDirectoryProperty(string targetRelativePath, Properties property, string value)
        {
            DirectoryEntry entry = new DirectoryEntry(String.Format("{0}/{1}", WebSiteRootPath, targetRelativePath));
            entry.Properties[property.ToString()].Value = value;
            entry.CommitChanges();
        }

        public static void SetUser(string ObjectPath, string UserName, string Password)
        {
            DirectoryEntry webRoot = new DirectoryEntry(WebSiteRootPath);
            webRoot.Properties[AnonymousUserName].Value = UserName;
            webRoot.Properties[AnonymousUserPass].Value = Password;
            webRoot.CommitChanges();
        }

        public static void SetBinding(IPAddress IP)
        {
            SetBinding(IP, -1);
        }

        public static void SetBinding(IPAddress IP, int Port)
        {
            const byte ipIndex = 0;
            const byte portIndex = 1;
            //const byte hostIndex = 2;

            DirectoryEntry webRoot = new DirectoryEntry(DefaultWebSitePath);

            string[] currentBinding = webRoot.Properties[ServerBindings].Value.ToString().Split(':');

            if (IP != null)
                currentBinding[ipIndex] = IP.ToString();

            if (Port > 0)
                currentBinding[portIndex] = Port.ToString();

            webRoot.Properties[ServerBindings].Value = String.Join(":", currentBinding);
            webRoot.CommitChanges();
        }

        public static OperationResult<bool> CreateVirtualDirectory(string server, string virtualDirectoryName, string path, bool asApplication)
        {
            DirectoryEntry root = new DirectoryEntry(Regex.Replace(String.Format(WebSiteRootPathF, server, parent), @"/$", ""));
            DirectoryEntries children = root.Children;
            DirectoryEntry newEntry = children.Add(name, root.SchemaClassName);

            newEntry.Properties["path"].Value = path;

            if (asApplication)
            {
                newEntry.Invoke("AppCreate", true);
                newEntry.Properties["AppFriendlyName"][0] = name;
            }

            newEntry.CommitChanges();

            return new OperationResult<bool>(true);
        }

        public static DataOperationResult<bool> DeleteVirtualDirectory(string server, string parent, string name)
        {
            string path = Regex.Replace(String.Format(WebSiteRootPathF, server, parent), @"/$", "");
            DirectoryEntry root = new DirectoryEntry(path);

            foreach (DirectoryEntry directoryEntry in root.Children)
            {
                if(directoryEntry.Name == name)
                {
                    root.Invoke("Delete", new string[] {directoryEntry.SchemaClassName, name});
                    root.CommitChanges();
                    return new DataOperationResult<bool>(true, true);
                }
            }

            return new DataOperationResult<bool>(true, false);
        }
    }
}
